package cn.net.awit.API.controller;

import cn.net.awit.API.entity.JSONResult;
import cn.net.awit.API.util.RedisForValue;
import cn.net.awit.API.util.StrToJSONUtil;
import cn.net.awit.weaforcast.entity.WeaForcastEntity;
import cn.net.awit.weaforcast.service.WeaForcastServiceI;
import cn.net.awit.weaforcastdata.entity.WeaForcastDataEntity;
import cn.net.awit.weaforcastdata.service.WeaForcastDataServiceI;
import cn.net.awit.weastation.entity.WeaStationEntity;
import cn.net.awit.weastation.service.WeaStationServiceI;
import cn.net.awit.weastationdata.entity.WeaStationDataEntity;
import cn.net.awit.weastationdata.service.WeaStationDataServiceI;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.jeecgframework.core.common.controller.BaseController;
import org.jeecgframework.core.constant.Globals;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.web.system.pojo.base.TSUser;
import org.jeecgframework.web.system.service.SystemService;
import org.jeecgframework.web.system.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**   
 * @Title: Controller  
 * @Description: 气象站管理
 * @author onlineGenerator
 * @date 2018-10-29 09:33:37
 * @version V1.0   
 *
 */
@Controller
@RequestMapping("/push")
public class PushDataController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(PushDataController.class);

	@Autowired
	private UserService userService;
	@Autowired
	private SystemService systemService;
	@Autowired
	private WeaStationDataServiceI weaStationDataService;
	@Autowired
	private WeaForcastDataServiceI weaForcastDataService;
	@Autowired
	private WeaStationServiceI weaStationService;
	@Autowired
	private WeaForcastServiceI weaForcastService;
	@Autowired
	@Qualifier("redisForValue")
	private RedisForValue redisUtil;
	
	private static final String TIME_PATTERN="yyyyMMddHH";
	
	/**
	 * 推送JSON数据内容
	 * code:0-success,1-failed
	 * @return
	 */
	@RequestMapping(params = "pushData")
	@ResponseBody
	public JSONResult pushData(HttpServletRequest request,String username,String password) {
		JSONResult jsonResult = new JSONResult(0, "push data sucessful.");
		try{
			//当无法接收到用户名和密码的时候，提示用户参数缺失
			if(username==null || "".equals(username) || password==null || "".equals(password)){
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but param is losed.");
				systemService.addApiLog("push/pushData:无参数!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,null);
				return jsonResult;
			}
			TSUser user = new TSUser();
			user.setUserName(username);
			user.setPassword(password);
			TSUser u = userService.checkUserExits(user);
			if(u==null){	//用户名和密码登录验证失败
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but username or password validate failed.");
				systemService.addApiLog("push/pushData:登录失败!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				return jsonResult;
			}
			if (u != null && u.getStatus() != 0) {	//验证成功且被激活
				String jsonData = parseRequest(request);
//				jsonResult.addObj("jsonRes", jsonData);
				logger.info("dataPush:【"+jsonData+"】");
				if(jsonData==null || "".equals(jsonData)){
					jsonResult.setCode(1);
					jsonResult.setMsg("validate successful,but no data");
					systemService.addApiLog("push/pushData:无数据!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
					return jsonResult;
				}
				List<Map<String, Object>> list = StrToJSONUtil.getList(jsonData);
				//解析存入数据库
				jsonResult=praseListToData(list, jsonResult);
				if(jsonResult.getCode()==1){
					systemService.addApiLog("push/pushData:dataStr【"+jsonData+"】,msg【"+jsonResult.getMsg()+"】", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				}
			}else{	//验证成功但是未被激活
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but you have not bean activated.");
				systemService.addApiLog("push/pushData:用户未激活。", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				return jsonResult;
			}
		}catch(Exception e){
//			e.printStackTrace();
			jsonResult.setCode(1);
			jsonResult.setMsg("push data failed.");
			jsonResult.addObj("error", e.getMessage());
			systemService.addApiLog("push/pushData:500,"+e.getMessage(), Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_ERROR,null);
//			throw new BusinessException(e.getMessage());
		}
		return jsonResult;
	}
	
	/**
	 * 推送JSON数据内容
	 * code:0-success,1-failed
	 * @return
	 */
	@RequestMapping(params = "pushStation")
	@ResponseBody
	public JSONResult pushStation(HttpServletRequest request,String username,String password) {
		JSONResult jsonResult = new JSONResult(0, "push station data sucessful.");
		try{
			//当无法接收到用户名和密码的时候，提示用户参数缺失
			if(username==null || "".equals(username) || password==null || "".equals(password)){
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but param is losed.");
				systemService.addApiLog("push/pushStation:无参数!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,null);
				return jsonResult;
			}
			TSUser user = new TSUser();
			user.setUserName(username);
			user.setPassword(password);
			TSUser u = userService.checkUserExits(user);
			if(u==null){	//用户名和密码登录验证失败
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but username or password validate failed.");
				systemService.addApiLog("push/pushStation:登录失败!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				return jsonResult;
			}
			if (u != null && u.getStatus() != 0) {	//验证成功且被激活
				String jsonData = parseRequest(request);
				logger.info("stationPush:【"+jsonData+"】");
				if(jsonData==null || "".equals(jsonData)){
					jsonResult.setCode(1);
					jsonResult.setMsg("validate successful,but no data");
					systemService.addApiLog("push/pushStation:无数据!", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
					return jsonResult;
				}
				//解析存入数据库
				Map<String, Object> mapObj = StrToJSONUtil.getMapObj(jsonData);
				jsonResult=parseMapToData(mapObj, jsonResult);
				//logger.info("stationPush:【"+jsonData+"】");
				if(jsonResult.getCode()==1){
					systemService.addApiLog("push/pushStation:dataStr【"+jsonData+"】,msg【"+jsonResult.getMsg()+"】", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				}
			}else{	//验证成功但是未被激活
				jsonResult.setCode(1);
				jsonResult.setMsg("conncted,but you have not bean activated.");
				systemService.addApiLog("push/pushStation:用户未激活。", Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_INFO,u);
				return jsonResult;
			}
		}catch(Exception e){
//			e.printStackTrace();
			jsonResult.setCode(1);
			jsonResult.setMsg("push data failed.");
			jsonResult.addObj("error", e.getMessage());
			systemService.addApiLog("push/pushStation:500,"+e.getMessage(), Globals.Log_Type_PUSHDATA, Globals.Log_Leavel_ERROR,null);
//			throw new BusinessException(e.getMessage());
		}
		return jsonResult;
	}
	
	private JSONResult parseMapToData(Map<String, Object> map,JSONResult jsonResult){
		List<WeaStationEntity> stationList = weaStationService.findByProperty(WeaStationEntity.class, "stationStatus", 1);	//已经激活的预报点信息
		Map<String, WeaStationEntity> stationMap=new HashMap<>();
		try {
			for(WeaStationEntity stationEntity:stationList){
				String stationCode = stationEntity.getStationCode();
				if(StringUtil.isNotEmpty(stationCode)){
					stationMap.put(stationCode, stationEntity);
				}
			}
		} catch (Exception e) {
			jsonResult.setCode(1);
			jsonResult.setMsg("系统异常，联系管理员！");
			jsonResult.addObj("error", e.getMessage());
			jsonResult.addObj("ecode", "20001");
			return jsonResult;
		}
		try {
			WeaStationDataEntity weaStationDataEntity = new WeaStationDataEntity();
			String autoStationId=((Map<String, String>)map.get("id")).get("autoStationId");
			weaStationDataEntity.setStationCode(autoStationId);
			String datetime=((Map<String, String>)map.get("id")).get("datetime");
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
			Date dataTime = formatter.parse(datetime);
			weaStationDataEntity.setDataTime(dataTime);
			
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rhumIn","rhumIn");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rhumOut","rhumOut");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"tempIn","tempIn");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"tempOut","tempOut");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"solarRadia","solarRadia");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"uv","uv");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"barometer","barometer");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"wind","wind");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"windDirc","windDirc");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"winAve","winAve");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rainRate","rainRate");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rainDay","rainDay");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rainMonth","rainMonth");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"rainYear","rainYear");
			weaStationDataEntity=setAttribute(weaStationDataEntity,map,"conBattery","consoleBatteryV");
			
			Object temp0=((List<Map<String, Object>>)map.get("ice")).get(0).get("temp0");
			weaStationDataEntity.setIce0Temp(Double.parseDouble(temp0.toString()));
			Object iceThick0=((List<Map<String, Object>>)map.get("ice")).get(0).get("iceThick0");
			weaStationDataEntity.setIce0Thick(Double.parseDouble(iceThick0.toString()));
			Object alarm0_0=((List<Map<String, Object>>)map.get("ice")).get(0).get("alarm0[0]");
			Object alarm0_1=((List<Map<String, Object>>)map.get("ice")).get(0).get("alarm0[1]");
			Object alarm0_2=((List<Map<String, Object>>)map.get("ice")).get(0).get("alarm0[2]");
			alarm0_0=alarm0_0==null?0:alarm0_0;
			alarm0_1=alarm0_1==null?0:alarm0_1;
			alarm0_2=alarm0_2==null?0:alarm0_2;
			weaStationDataEntity.setIce0Alarm(alarm0_0.toString()+alarm0_1.toString()+alarm0_2.toString());
			Object temp1=((List<Map<String, Object>>)map.get("ice")).get(1).get("temp1");
			weaStationDataEntity.setIce1Temp(Double.parseDouble(temp1.toString()));
			Object iceThick1=((List<Map<String, Object>>)map.get("ice")).get(1).get("iceThick1");
			weaStationDataEntity.setIce1Thick(Double.parseDouble(iceThick1.toString()));
			Object alarm1_0=((List<Map<String, Object>>)map.get("ice")).get(1).get("alarm1[0]");
			Object alarm1_1=((List<Map<String, Object>>)map.get("ice")).get(1).get("alarm1[1]");
			Object alarm1_2=((List<Map<String, Object>>)map.get("ice")).get(1).get("alarm1[2]");
			alarm1_0=alarm1_0==null?0:alarm1_0;
			alarm1_1=alarm1_1==null?0:alarm1_1;
			alarm1_2=alarm1_2==null?0:alarm1_2;
			weaStationDataEntity.setIce1Alarm(alarm1_0.toString()+alarm1_1.toString()+alarm1_2.toString());
			
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,7,"tempExtra","tempExtra");
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,4,"soilTemp","soilTemp");
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,4,"leafTemp","leafTemp");
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,7,"rhumExtra","rhumExtra");
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,4,"soilMoinst","soilMoinst");
			weaStationDataEntity=setAttrFor(weaStationDataEntity,map,4,"leafWet","leafWet");
			
			weaStationDataService.save(weaStationDataEntity);
		} catch (Exception e) {
//			e.printStackTrace();
			jsonResult.setCode(1);
			jsonResult.setMsg("数据异常，请检查数据！");
			jsonResult.addObj("error", e.getMessage());
			jsonResult.addObj("ecode", "20002");
			return jsonResult;
		}
		return jsonResult;
	}
	
	private WeaStationDataEntity setAttrFor(WeaStationDataEntity weaStationDataEntity, Map<String, Object> map,int count,String proName, String key){
		try {
			String res="";
			for(int i=0;i<count;i++){
				Object obj = map.get(key+(i+1));
				String val=obj==null?"":obj.toString();
				res+=val+",";
			}
			res=res.substring(0, res.lastIndexOf(","));
			Field f = weaStationDataEntity.getClass().getDeclaredField(proName);
			f.setAccessible(true);
			f.set(weaStationDataEntity, res);
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return weaStationDataEntity;
	}
	
	private WeaStationDataEntity setAttribute(WeaStationDataEntity weaStationDataEntity, Map<String, Object> map,String proName, String key){
		Object val = (Object) map.get(key);
		if(val!=null){
			try {
				Field f = weaStationDataEntity.getClass().getDeclaredField(proName);
				f.setAccessible(true);
				f.set(weaStationDataEntity, Double.parseDouble(val.toString()));
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return weaStationDataEntity;
	}
	
	/**
	 * 将list对象存入预报点数据
	 * @param list
	 * @param jsonResult
	 * @return
	 */
	private JSONResult praseListToData(List<Map<String, Object>> list,JSONResult jsonResult){
		List<WeaForcastEntity> forcastList = weaForcastService.findByProperty(WeaForcastEntity.class, "status", 1);	//已经激活的预报点信息
		Map<String, WeaForcastEntity> forcastMap=new HashMap<>();
		try {
			for (WeaForcastEntity weaForcastEntity : forcastList) {
				Double lng = weaForcastEntity.getLng();
				Double lat = weaForcastEntity.getLat();
				if(lng!=null && lat!=null && lng!=0 && lat!=0){
					forcastMap.put(lng+"-"+lat, weaForcastEntity);
				}
			}
		} catch (Exception e) {
			jsonResult.setCode(1);
			jsonResult.setMsg("系统异常，联系管理员！");
			jsonResult.addObj("error", e.getMessage());
			jsonResult.addObj("ecode", "10001");
			return jsonResult;
		}
		//数据的预报点
		String forcastId=null;
		List<WeaForcastDataEntity> forcastDataList=new ArrayList<>(); 
		Date groupDate = new Date();
		try {
			long[] timeArr=new long[list.size()-1];
			int timeIndex=0;
			for(Map<String, Object> map:list){
				Set<String> keySet = map.keySet();
				int size = keySet.size();
				if(size==2){
					if(map.get("lng")!=null && map.get("lat")!=null){
						WeaForcastEntity weaForcastEntity = forcastMap.get(map.get("lng")+"-"+map.get("lat"));
						forcastId =weaForcastEntity==null?null: weaForcastEntity.getId();
					}
				}else{
					WeaForcastDataEntity weaForcastDataEntity=new WeaForcastDataEntity();
					Date dateTime=StrToJSONUtil.getTime((String)map.get("time"), TIME_PATTERN);
					timeArr[timeIndex]=dateTime.getTime();
					timeIndex++;
					weaForcastDataEntity.setTime(dateTime);
					weaForcastDataEntity.setWd(Double.valueOf((String) map.get("wd")));
					weaForcastDataEntity.setWs(Double.valueOf((String) map.get("ws")));
					weaForcastDataEntity.setRain(Double.valueOf((String) map.get("rain")));
					weaForcastDataEntity.setSnow(Double.valueOf((String) map.get("snow")));
					weaForcastDataEntity.setCloud(Double.valueOf((String) map.get("cloud")));
					weaForcastDataEntity.setTd(Double.valueOf((String) map.get("td")));
					weaForcastDataEntity.setRh(Double.valueOf((String) map.get("rh")));
					weaForcastDataEntity.setTemp(Double.valueOf((String) map.get("temp")));
					weaForcastDataEntity.setSw(Double.valueOf((String) map.get("sw")));
					weaForcastDataEntity.setLw(Double.valueOf((String) map.get("lw")));
					weaForcastDataEntity.setP(Double.valueOf((String) map.get("p")));
					weaForcastDataEntity.setSoilt(Double.valueOf((String) map.get("soilt")));
					weaForcastDataEntity.setSoilm(Double.valueOf((String) map.get("soilm")));
					weaForcastDataEntity.setSoilw(Double.valueOf((String) map.get("soilw")));
					weaForcastDataEntity.setVis(Double.valueOf((String) map.get("vis")));
					weaForcastDataEntity.setStab(Double.valueOf((String) map.get("stab")));
					weaForcastDataEntity.setGroupKey(groupDate.getTime()+"");
					Object obj = map.get("freez");
					if(obj!=null){
						weaForcastDataEntity.setFreez(Integer.valueOf((String) obj));
					}else{
						weaForcastDataEntity.setFreez(0);
					}
					forcastDataList.add(weaForcastDataEntity);
				}
			}
			if(forcastId!=null){
				for(WeaForcastDataEntity weaForcastDataEntity:forcastDataList){
					weaForcastDataEntity.setForcastId(forcastId);
				}
				if(timeArr.length>0){
					Arrays.sort(timeArr);
					weaForcastDataService.executeSql("delete from wea_forcast_data where forcast_id=? and time>=?"
							,forcastId,new Date(timeArr[0]));
				}
				weaForcastDataService.batchSave(forcastDataList);
			}else{
				jsonResult.setCode(1);
				jsonResult.setMsg("平台无对应预报点["+forcastId+"]，请添加后重试！");
				jsonResult.addObj("ecode", "10003");
			}
		} catch (Exception e) {
			e.printStackTrace();
			jsonResult.setCode(1);
			jsonResult.setMsg("数据异常，请检查数据！");
			jsonResult.addObj("error", e.getMessage());
			jsonResult.addObj("ecode", "10002");
			return jsonResult;
		}
		return jsonResult;
	}
	
	private String parseRequest(HttpServletRequest request) throws UnsupportedEncodingException, IOException{
		InputStreamReader reader=new InputStreamReader(request.getInputStream(),"UTF-8");
		char[] b=new char[1024];
		int length=0;
		StringBuilder stringBuilder = new StringBuilder();
		while((length=reader.read(b))!=-1){
			String str=new String(b,0,length);
			stringBuilder.append(str);
		}
		return stringBuilder.toString();
	}
	
	
}
